package com.dao;

import com.model.Curriculum;
import com.model.StuException;
import com.model.Student;
import com.util.XmlUtil;
import org.dom4j.Document;
import org.dom4j.Element;

import java.sql.Struct;
import java.util.ArrayList;
import java.util.List;
import java.util.Vector;

/**
 * Created by guin_guo on 2015/10/27.
 * 完成对学生对象的增删改查
 */
public class StudentDao {
    private static final String STUS_XML="students.xml";
    private Document sd;
    private CurriculumDao ccd;

    private StudentDao() {
        sd = XmlUtil.getStuDocument();
        ccd = CurriculumDao.getInstance();
    }
    private static class Singleton{
        public static StudentDao instance = new StudentDao();
    }

    /**
     * 使用StudentDao.getInstance()获取Dao的单例
     * @return
     */
    public static StudentDao getInstance(){
        return (Singleton.instance);
    }
    private void write(){
        XmlUtil.write2XML(sd,STUS_XML);
    }

    /**
     * 添加学生接口
     * @param student
     */
    public void add(Student student) {
        if("".equals(student.getAccount())||student.getAccount()==null){
            throw new StuException("用户名不能为空");
        }
        Student s = this.loadByAccount(student.getAccount());
        if(s!=null) {
            throw new StuException("学生信息已存在，不能继续添加");
        }
        Element es = sd.getRootElement().addElement("student");
        es.addAttribute("id", String.valueOf(XmlUtil.getMaxId(sd,"/students/student")+1));
        es.addElement("account").addText(student.getAccount());
        es.addElement("name").addText(student.getName());
        es.addElement("sex").addText(student.getSex());
        es.addElement("birth").addText(student.getBirth());
        //初始密码默认是学号
        es.addElement("password").addText(student.getAccount());
        es.addElement("age").addText(student.getAge());
        es.addElement("from").addText(student.getFrom());
        es.addElement("status").addText(student.getStatus());
        es.addElement("major").addText(student.getMajor());
        es.addElement("college").addText(student.getCollege());
        write();
        if (ccd.loadByStudent(student.getAccount()) == null) {
            Curriculum curriculum = ccd.loadByName(student.getMajor());
            if(curriculum!=null){
                curriculum.setStudent(student.getAccount());
                ccd.add(curriculum);
            }
        }
    }
    public void delete(String accoutn) {
        Element root = sd.getRootElement();
        Element s = loadElementByAccount(accoutn);
        if(s==null) {
            throw new StuException("要删除的学生不存在");
        }
        root.remove(s);
        write();
    }

    /**
     * 更新接口
     * @param student
     */
    public void update(Student student) {
        Element e = loadElementByAccount(student.getAccount());
        if (e == null) {
            throw new StuException("要更新的学生不存在");
        }
        e.element("name").setText(student.getName());
        e.element("sex").setText(student.getSex());
        e.element("from").setText(student.getFrom());
        e.element("birth").setText(student.getBirth());
        e.element("age").setText(student.getAge());
        e.element("status").setText(student.getStatus());
        e.element("college").setText(student.getCollege());
        e.element("major").setText(student.getMajor());
        e.element("password").setText(student.getPassword());
        write();
    }

    /**
     * 根据学号找学生
     * @param account
     * @return
     */
    public Student loadByAccount(String account) {
        Element e = loadElementByAccount(account);
        if (e == null) {
            return null;
        }
        Student student = eLement2Stu(e);
        return student;
    }

    /**
     * 根据姓名找学生
     * @param name
     * @return
     */
    public Student loadByName(String name) {
        Element e = loadElementByName(name);
        if (e == null) {
            return null;
        }
        Student student = eLement2Stu(e);
        return student;
    }

    /**
     * 返回所有学生信息
     * @return
     */
    public List<Student> list(){
        String path = "/students/student";
        List<Element> eles = sd.selectNodes(path);
        List<Student> students = new ArrayList<Student>(eles.size());
        for (Element e : eles) {
            students.add(eLement2Stu(e));
        }
        return students;
    }

    /**
     * 返回一组Vector，里面放的是Student
     * @return
     */
    public List<Vector> vectorList(){
        List<Student> students = this.list();
        return stu2Vector(students);
    }

    /**
     * 通过专业班级查找旗下的学生
     * @param major
     * @return List里面是vector
     */
    public List<Vector> vectorListByMajor(String major){
        String path = "/students/student[major='"+major+"']";
        List<Element> eles = sd.selectNodes(path);
        List<Student> students = new ArrayList<Student>(eles.size());
        for (Element e : eles) {
            students.add(eLement2Stu(e));
        }
        return stu2Vector(students);
    }
    /**
     * 通过专业班级查找旗下的学生
     * @param major
     * @return List里面是vector
     */
    public List<Student> listByMajor(String major){
        String path = "/students/student[major='"+major+"']";
        List<Element> eles = sd.selectNodes(path);
        List<Student> students = new ArrayList<Student>(eles.size());
        for (Element e : eles) {
            students.add(eLement2Stu(e));
        }
        return students;
    }
    /**
     * 把一个List的Student转为List的vector
     * @param students
     * @return List<Vector>
     */
    private List<Vector> stu2Vector(List<Student> students){
        List<Vector> list = new ArrayList<>(students.size());
        for (Student s: students) {
            Vector<String> vector = new Vector<>();
            vector.add(s.getAccount());
            vector.add(s.getName());
            vector.add(s.getAge());
            vector.add(s.getSex());
            vector.add(s.getBirth());
            vector.add(s.getFrom());
            vector.add(s.getStatus());
            vector.add(s.getCollege());
            vector.add(s.getMajor());
            list.add(vector);
        }
        return list;
    }
    /**
     * 通过学号查询学生
     * @param account 学号
     * @return 存在即返回一行学生信息，不存在返回空
     */
    public List<String> findByAccount(String account){
        Student s = this.loadByAccount(account);
        if(s==null){
            return null;
        }
        List<String> list = new ArrayList<>(1);
        list.add(s.getAccount());
        list.add(s.getName());
        list.add(s.getAge());
        list.add(s.getSex());
        list.add(s.getBirth());
        list.add(s.getFrom());
        list.add(s.getStatus());
        list.add(s.getCollege());
        list.add(s.getMajor());
        return list;
    }
    /**
     * 通过姓名查询学生
     * @param name 学号
     * @return 存在即返回一行学生信息，不存在返回空
     */
    public List<Vector> findByName(String name){
        Student s = this.loadByName(name);
        if(s==null){
            return null;
        }
        List<Vector> list = new ArrayList<>(1);
        Vector<String> vector = new Vector<>();
        vector.add(s.getAccount());
        vector.add(s.getName());
        vector.add(s.getAge());
        vector.add(s.getSex());
        vector.add(s.getBirth());
        vector.add(s.getFrom());
        vector.add(s.getStatus());
        vector.add(s.getCollege());
        vector.add(s.getMajor());
        list.add(vector);
        return list;
    }

    /**
     * 登录接口
     * @param account
     * @param password
     * @return
     */
    public Student login(String account,String password) {
        Student student = loadByAccount(account);
        if(student==null) throw new StuException("用户名不正确!");
        if(!student.getPassword().equals(password)) throw new StuException("密码不正确!");
        return student;
    }

    /**
     * Student Element to Student
     * @param e
     * @return
     */
    private Student eLement2Stu(Element e) {
        Student student = new Student();
        student.setId(Integer.parseInt(e.attributeValue("id")));
        student.setAccount(e.elementText("account"));
        student.setPassword(e.elementText("password"));
        student.setBirth(e.elementText("birth"));
        student.setCollege(e.elementText("college"));
        student.setName(e.elementText("name"));
        student.setStatus(e.elementText("status"));
        student.setMajor(e.elementText("major"));
        student.setFrom(e.elementText("from"));
        student.setSex(e.elementText("sex"));
        student.setAge(e.elementText("age"));
        return student;
    }

    /**
     * 根据学号找Element
     * @param account
     * @return
     */
    private Element loadElementByAccount(String account){
        String path = "/students/student[account='"+account+"']";
        Element e = (Element)sd.selectSingleNode(path);
        return e;
    }

    /**
     * 根据姓名找Element
     * @param name
     * @return
     */
    private Element loadElementByName(String name){
        String path = "/students/student[name='"+name+"']";
        Element e = (Element)sd.selectSingleNode(path);
        return e;
    }


    /**
     *  返回一组专业名称
     * @return
     */
    public String[] getMajorList() {
        List<Student> l = this.list();
        List<String> majors = new ArrayList<>(l.size());

        l.stream().forEach(value -> {
            if (!majors.contains(value.getMajor())) {
                majors.add(value.getMajor());
            }
        });
        String[] major = new String[majors.size()];
        for (int i = 0; i < majors.size(); i++) {
            major[i] = majors.get(i);
        }
        return major;
    }

}
